package com.bmmtwabp.employeedashbord.service.impl;

import com.bmmtwabp.employeedashbord.dao.*;
import com.bmmtwabp.employeedashbord.domain.Heat;
import com.bmmtwabp.employeedashbord.service.HeatService;
import com.bmmtwabp.employeedashbord.util.*;
import com.bmmtwabp.employeedashbord.vo.*;
import com.bmmtwabp.employeedashbord.vo.TemplateVo;
import java.util.*;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @Description: 热饭-实现类
 * @Param:
 * @return:
 * @Author: fenghouzhi
 * @Date: 2018/8/28
 */
@Slf4j
@Service
public class HeatServiceImpl implements HeatService {

  @Value("${heat.time}")
  private Integer heatTime;

  @Resource
  private HeatMapper heatMapper;

  @Resource
  private MicroWaveMapper microWaveMapper;

  @Override
  public Heat getWaitFirstHeat(String zoneName) {
    Heat waitFirstHeat = heatMapper.getWaitFirstHeat(zoneName);
    return waitFirstHeat;
  }

  @Override
  public List<HeatVo> getHeatListForApp(String zoneName) {
    List<HeatVo> heatVoList = heatMapper.getHeatListForApp(zoneName);
    if (heatVoList != null && heatVoList.size() > 0) {
      heatVoList = formatHeatVoList(heatVoList);
    }
    return heatVoList;
  }

  @Override
  public Integer getHistoryHeatSum(String zoneName) {
    return heatMapper.getHistoryHeatSum(zoneName);
  }

  @Override
  public Integer getWaitHeatSum(String zoneName) {
    return heatMapper.getWaitHeatSum(zoneName);
  }

  @Override
  public String getHeatingNickName(String zoneName) {
    return heatMapper.getHeatingNickName(zoneName);
  }

  @Override
  public String getUserHeatStatusByZoomName(String openId, String zoneName) {
    return heatMapper.getUserHeatStatusByZoomName(openId, zoneName);
  }

  @Override
  public Integer insertHeat(Heat heat) {
    Integer waitHeatSum = heatMapper.getWaitHeatSum(heat.getZone());
    Integer readyHeatSum = heatMapper.getReadyHeatSum(heat.getZone());
    Integer heatingSum = heatMapper.getHeatingSum(heat.getZone());

    log.info("等待人数：   " + waitHeatSum);
    log.info("准备人数：   " + readyHeatSum);
    log.info("热饭人数：   " + heatingSum);

    String waitTime = DateUtil.getDateTime();
    heat.setWaitTime(waitTime);
    if (waitHeatSum == 0 && readyHeatSum == 0 && heatingSum == 0) {
      heat.setHeatStatus(1);
      heatMapper.insertHeat(heat);
      CodeUtil.WAIT_HEAT_MAP.put(heat.getZone(), heat);
      return 1;
    } else {
      heat.setHeatStatus(0);
      heatMapper.insertHeat(heat);
      return 0;
    }

  }

  @Override
  public Heat getReadyByOpenId(String zoneName) {
    Heat heat = heatMapper.getReadyHeat(zoneName);
    return heat;
  }

  @Override
  public Integer readyHeat(String openId, String zoneName, String startWaitTime) {
    return heatMapper.readyHeat(openId, zoneName, startWaitTime);
  }

  @Override
  public Integer startHeat(String openId, String zoneName) {

    log.info("开始热饭  open info:  " + openId);
    String startTime = DateUtil.getDateTime();

    Integer result = heatMapper.startHeat(openId, startTime, zoneName);
    if (result == 1) {
      Heat heat = heatMapper.getHeatInfoByOpenIdAndStartTime(openId, startTime, zoneName);
      CodeUtil.WAIT_HEAT_MAP.put(heat.getZone(), heat);
      microWaveMapper.updateMicroWaveStatus(CodeUtil.MICROWAVE_USED, zoneName);
    }
    return result;
  }

  @Override
  public Integer overHeat(String openId, String zoneName) {

    Heat heat = heatMapper.getHeatingInfoByOpenId(openId, zoneName, 2);

    if (heat == null) {
      log.info("未找到当前用户热饭记录");
      return 0;
    }

    String zoomName = heat.getZone();
    String endTime = DateUtil.getDateTime();
    Integer result = heatMapper.overHeat(openId, endTime, zoneName);
    if (result == 1) {
      CodeUtil.WAIT_HEAT_MAP.remove(zoneName);
      microWaveMapper.updateMicroWaveStatus(CodeUtil.MICROWAVE_NOTUSED, zoomName);
      setWaitHeat(zoneName);
      return result;
    } else {
      log.info("结束热饭失败！");
      return 0;
    }

  }

  @Override
  public Integer cancelHeat(String openId, String zoneName) {
    Integer result = heatMapper.cancelHeat(openId, zoneName);
    if (result == 1) {
      String msg = "1," + openId + ",有用户取消热饭";
      WebSocketUtil.sendMessageForAll(msg);
      return result;
    } else {
      return 0;
    }
  }

  @Override
  public Integer overHeatByHeatId(Long heatId) {
    String endTime = DateUtil.getDateTime();
    Heat heat = heatMapper.getHeatInfoById(heatId);
    String zoom = heat.getZone();

    Integer result = heatMapper.overHeatByHeatId(heatId, endTime);
    if (result == 1) {
      CodeUtil.WAIT_HEAT_MAP.remove(zoom);
      microWaveMapper.updateMicroWaveStatus(CodeUtil.MICROWAVE_NOTUSED, heat.getZone());
      setWaitHeat(zoom);
      return result;
    } else {
      log.info("结束热饭失败！");
      return 0;
    }
  }

  @Override
  public List<HeatVo> getHeatVoList(QueryHeatVo queryHeatVo) {
    queryHeatVo.setNickName(queryHeatVo.getNickName().trim());
    log.info("heatStatusValue:    " + queryHeatVo.getHeatStatusValue());
    List<HeatVo> heatVoList = heatMapper.getHeatVoList(queryHeatVo);
    return heatVoList;
  }

  @Override
  public String getOpenIdForHeatTimeOut(String zoneName) {

    Heat heat = heatMapper.getHeatingInfoByZoom(zoneName);
    if (heat != null) {
      /**
       * 计算开始热饭时间到当前时间的时间差-若大于规定热饭的时间间隔将其设置为超时，让其结束热饭
       */
      Integer heatTimeLong = DateUtil.getTimeDifference(heat.getStartTime());
      if (heatTimeLong > CodeUtil.HEAT_TIME) {
        String endTime = DateUtil.getDateTime();
        heatMapper.overHeat(heat.getOpenId(), endTime, heat.getZone());
        microWaveMapper.updateMicroWaveStatus(CodeUtil.MICROWAVE_NOTUSED, heat.getZone());
        return heat.getOpenId();
      } else {
        return null;
      }
    } else {
      return null;
    }

  }

  @Override
  public void findTimeOutMethod(String zoneName) {
    String timeOutUserOpenId = getOpenIdForHeatTimeOut(zoneName);
    if (timeOutUserOpenId == null) {
      log.info("没有用户超时！");
    } else {
      log.info("超时用户openId info：  " + timeOutUserOpenId);
      Heat waitHeat = getWaitFirstHeat(zoneName);
      /**
       * 当前有等待的用户
       */
      if (waitHeat != null) {
        setWaitHeat(zoneName);
      } else {
        log.info("当前没有等待用户!!");
      }
    }
  }


  /**
   * 通知下一个用户准备热饭
   */
  @Override
  public void setWaitHeat(String zoneName) {
    Heat waitHeat = heatMapper.getWaitFirstHeat(zoneName);
    if (waitHeat != null) {
      /**
       * 重置开始准备热饭时间为当前时间
       */
      String startWaitTime = DateUtil.getDateTime();
      heatMapper.readyHeat(startWaitTime, waitHeat.getOpenId(), zoneName);
      waitHeat = getReadyByOpenId(zoneName);
      String textMsg = "轮到您开始热饭";
      CodeUtil.WAIT_HEAT_MAP.put(zoneName, waitHeat);
      sendTemplateMessage(waitHeat.getOpenId(), waitHeat.getFormId(), textMsg, zoneName);
      log.info("openid:  " + waitHeat.getOpenId() + "   进入准备热饭状态");
    } else {
      CodeUtil.WAIT_HEAT_MAP.remove(zoneName);
      log.info("当前没有等待热饭的人！");
    }
  }

  private List<HeatVo> formatHeatVoList(List<HeatVo> heatVoList) {

    for (HeatVo heatVo : heatVoList) {
      String startTime = heatVo.getStartTime();
      String endTime = heatVo.getEndTime();
      if (startTime != null && !"".equals(startTime)) {
        heatVo.setStartTime(startTime.substring(10, startTime.length()));
      }
      if (endTime != null && !"".equals(endTime)) {
        heatVo.setEndTime(endTime.substring(10, endTime.length()));
      }
    }
    return heatVoList;
  }

  /**
   * 组建微信模板消息的数据Map
   */
  private Map buildWxTemplateDataMap(String msg, String zoom) {
    String remark = "请前往 [" + zoom + "] 微波炉区~~";

    Map<String, Object> map = new HashMap<>(2);
    map.put("keyword1", new TemplateVo(msg));
    map.put("keyword2", new TemplateVo(remark));
    return map;
  }

  private void sendTemplateMessage(String openId, String formId, String textMsg, String zoom) {
    log.info("openId:{},formId:{},textMsg:{},zoom:{}", openId, formId, textMsg, zoom);
    String wxToken = CodeUtil.overdueDetection();
    String url = CodeUtil.WEIXIN_TEMPLATE_MESSAGE + wxToken;
    Map<String, Object> paramMap = new HashMap<>(7);
    paramMap.put("access_token", wxToken);
    paramMap.put("touser", openId);
    paramMap.put("template_id", CodeUtil.TEMPLATE_ID);
    paramMap.put("page", "/pages/index");
    paramMap.put("form_id", formId);
    paramMap.put("data", buildWxTemplateDataMap(textMsg, zoom));
    paramMap.put("emphasis_keyword", "keyword1.DATA");

    try {
      String responseData = HttpRequestUtil.httpPost(url, paramMap);
      log.info("res info:   " + responseData);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}
